package com.module.base.ext

import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope

/**
 * 倒计时处理，扩展函数
 */

/**
 * 使用Flow实现一个倒计时功能
 */
fun FragmentActivity.countDownByFlow(
    max: Int,
    onTick: (Int) -> Unit,
    onFinish: (() -> Unit)? = null,
): Job {
    return countDownByFlow(max, lifecycleScope, onTick, onFinish)
}

/**
 * 使用Flow实现一个倒计时功能
 */
fun Fragment.countDownByFlow(
    max: Int,
    onTick: (Int) -> Unit,
    onFinish: (() -> Unit)? = null,
): Job {
    return countDownByFlow(max, lifecycleScope, onTick, onFinish)
}

/**
 * 使用Flow实现一个倒计时功能
 */
fun ViewModel.countDownByFlow(
    max: Int,
    onTick: (Int) -> Unit,
    onFinish: (() -> Unit)? = null,
): Job {
    return countDownByFlow(max, viewModelScope, onTick, onFinish)
}

/**
 * 使用Flow实现一个倒计时功能
 */
fun countDownByFlow(
    max: Int,
    scope: CoroutineScope,
    onTick: (Int) -> Unit,
    onFinish: (() -> Unit)? = null,
): Job {
    return flow {
        for (num in max downTo 0) {
            emit(num)
            if (num != 0) delay(1000)
        }
    }.flowOn(Dispatchers.Main)
        .onEach { onTick.invoke(it) }
        .onCompletion { cause -> if (cause == null) onFinish?.invoke() }
        .launchIn(scope) //保证在一个协程中执行
}


/**
 * 循环计时
 */
fun cycleTiming(
    scope: CoroutineScope,
    timeMillis: Long,
    onTick: () -> Unit
): Job {
    return flow {
        while (true) {
            delay(timeMillis)
            emit(true)
        }
    }.flowOn(Dispatchers.Main)
        .onEach {
            onTick.invoke()
        }
        .launchIn(scope) //保证在一个协程中执行
}
